package com.service.impl;

import com.alibaba.fastjson.JSON;
import com.dao.PermissionResourceMapper;
import com.dao.PermissionRoleResourceMapper;
import com.dao.PermissionSysUserRoleMapper;
import com.dao.SysUserMapper;
import com.model.PermissionResource;
import com.model.PermissionSysUserRole;
import com.model.SysUser;
import com.po.PermissionSysUserRolePO;
import com.po.SysUserRoleSaveBatchPO;
import com.service.PermissionSysUserRoleService;
import com.utils.BuildTree;
import com.utils.Tree;
import com.vo.PermissionSysUserRoleVO;
import com.vo.ResourceVO;
import com.vo.SysUserRoleResourceVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.testng.collections.Lists;

import java.util.*;

/**
 * @Author: chihaojie
 * @Date: 2019/5/29 16:35
 * @Version 1.0
 * @Note
 */
@Slf4j
@Service
public class PermissionSysUserRoleServiceImpl implements PermissionSysUserRoleService {


    @Autowired
    private PermissionSysUserRoleMapper permissionSysUserRoleMapper;

    @Autowired
    private PermissionRoleResourceMapper permissionRoleResourceMapper;

    @Autowired
    private PermissionResourceMapper permissionResourceMapper;

    @Autowired
    private SysUserMapper     sysUserMapper;

    public static  final  List<String> asList=Lists.newArrayList( Arrays.asList("21","23","45","7","30","43","31","33","10","11","54"));

    @Override
    public PermissionSysUserRoleVO save(PermissionSysUserRolePO permissionResourcePO) {
        return null;
    }


    @Transactional
    @Override
    public Boolean saveSysUserRoleBatch(SysUserRoleSaveBatchPO sysUserRoleSaveBatchPO) {
        boolean flag = false;
        if (!ObjectUtils.isEmpty(sysUserRoleSaveBatchPO)
                && (!sysUserRoleSaveBatchPO.getRoleIdList().isEmpty())) {
            //先删除之前的关系
            permissionSysUserRoleMapper.deleteByAccountId(sysUserRoleSaveBatchPO.getAccountId());
            // 插入
            for (Long roleId : sysUserRoleSaveBatchPO.getRoleIdList()) {
                PermissionSysUserRole  userRole = new PermissionSysUserRole();
                userRole.setUserId(sysUserRoleSaveBatchPO.getAccountId());
                userRole.setRoleId(roleId);
                permissionSysUserRoleMapper.insert(userRole);
            }
            flag = true;
        }
        return flag;
    }

    @Override
    @Transactional
    public Boolean removeAccountRole(Long id) {
        permissionSysUserRoleMapper.deleteByPrimaryKey(id);
        return true;
    }


    @Override
    public SysUserRoleResourceVO getRoleResourceByAccountId(Long accountId) {
        SysUserRoleResourceVO  vo = new SysUserRoleResourceVO();
        List<ResourceVO> resourceVOS=Lists.newArrayList();
        //TODO 对root用户进行特殊处理
        SysUser user = sysUserMapper.selectByPrimaryKey(accountId);

        //查询该账号所对应角色集合
        List<Long> roleIdList=permissionSysUserRoleMapper.selectRoleIdListByAccountId(accountId);
        System.out.println("账号所对应角色集合:"+ JSON.toJSONString(roleIdList));
        if(ObjectUtils.isEmpty(roleIdList)){
            roleIdList=Lists.newArrayList();
            List<Tree<ResourceVO>> idsTree=Lists.newArrayList();
            vo.setRoleIdList(roleIdList);
            vo.setResourceTree(idsTree);
            return vo;
        }
        vo.setAccoundId(accountId);
        vo.setRoleIdList(roleIdList);
        //根据角色集合获取资源集合
        List<Long> resourceIdList=  permissionRoleResourceMapper.selectResourceIdList(roleIdList);
        System.out.println("角色集合获取资源集合:"+ JSON.toJSONString(resourceIdList));
        //获取
        //查询所有的资源集合
        for (Long resourceId:resourceIdList) {
            PermissionResource resource = permissionResourceMapper.selectByPrimaryKey(resourceId);
            ResourceVO  voTop=new ResourceVO();
            BeanUtils.copyProperties(resource,voTop);
            voTop.setLevel(resource.getLevel().intValue());
            resourceVOS.add(voTop);
        }
        //创建一个树集合
        List<Tree<ResourceVO>> trees = new ArrayList<Tree<ResourceVO>>(resourceVOS.size());
        //遍历资源集合
        for (ResourceVO  c: resourceVOS) {
            Tree<ResourceVO> tree = new Tree<ResourceVO>(c.getId(), c.getName(), c.getParentId());
            Map<String, Object> attributes = new HashMap<String, Object>();
            attributes.put("level", c.getLevel());
            attributes.put("status", c.getStatus());
            tree.setName(c.getName());
            tree.setComment(c.getComment());
            tree.setParentId(c.getParentId()+"");
            tree.setLevel(String.valueOf(c.getLevel()));
            tree.setLevel(c.getLevel()+"");
            tree.setUrl(c.getUrl());
            tree.setMethod(c.getMethod());
            tree.setAttributes(attributes);
            tree.setChecked(true);
            trees.add(tree);
        }
        List<Tree<ResourceVO>> topNodes = BuildTree.getTopNodes(trees);
        List<Tree<ResourceVO>> realNodes=Lists.newArrayList();
        //过滤
        List<Tree<ResourceVO>>  excludeList=Lists.newArrayList();
        if(user.getUserType().equals(1)){
            for (Tree<ResourceVO>  resource: topNodes) {
                excludeList = recurseSingleNode(resource,asList, excludeList);

            }
        }
        System.out.println("需要过滤的的节点是： "+excludeList);
        vo.setResourceTree(topNodes);
        return vo;
    }

    private List<Tree<ResourceVO>>  recurseSingleNode(Tree<ResourceVO> resource,List<String> asList, List<Tree<ResourceVO>> excludeList) {
        String id = resource.getId();
        List<Tree<ResourceVO>> childrenNode = resource.getChildrenNode();
        if(asList.contains(id)){
            excludeList.add(resource);
            resource.setIsShow(false);
            resource.setShow(false);
            return excludeList;
        }
        //递归检查
        if(ObjectUtils.isEmpty(childrenNode)){
            return excludeList;
        }else {
            for (Tree<ResourceVO> subNode: childrenNode) {
                excludeList = recurseSingleNode(subNode,asList, excludeList);
            }
            return excludeList;
        }
    }
}
